﻿using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint.ApplicationPages;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Web.UI.WebControls;

namespace SharePointHNSC.ApplicationPages
{
    public partial class CreateHostNamedSitePage : DialogAdminPageBase
    {
        protected PeopleEditor PickerOwner;
        protected PeopleEditor PickerOwner2;
        protected TextBox TxtCreateSiteTitle;
        protected TextBox TxtSiteName;
        protected TextBox TxtCreateSiteDescription;
        protected DropDownList DdlLanguage;
        protected DropDownList DdlQuotaTemplate;
        protected DropDownList DdlContentDatabase;
        protected DropDownList DdlHostHeaderPrefixes;
        protected Button BtnCreateSite;
        protected Button BtnCreateSiteTop;
        protected Button BtnSkipSite;
        protected Button BtnSkipSiteTop;
        protected Label LabelCreateSiteMessage;
        protected Label LabelErrorMessage;
        protected Label LabelStorageQuota;
        protected Label LabelUserQuota;
        protected Label LabelAnonAllowed;
        protected Literal LiteralHiddenQuotaTemplates;
        protected RequiredFieldValidator ReqValSiteName;
        protected CustomValidator CusValSiteName;
        protected RequiredFieldValidator ValOwnerLogin;
        protected RequiredFieldValidator ValOwnerEmail;
        protected RequiredFieldValidator ValLanguage;
        protected CustomValidator CusValSecondOwner;
        protected ValidationSummary ValSummary;
        protected DelegateControl DelctlCreateSiteCollectionPanel;
        protected WebApplicationSelector Selector;
        protected TemplatePicker InputFormTemplatePickerControl;
        protected InputFormSection idWebApplicationSelectorSection;
        protected InputFormSection idPrimaryAdministratorSection;
        protected InputFormSection idSecondaryAdministratorSection;
        protected InputFormSection idQuotaSection;
        protected string HideLeftNavString = "";

        string SiteUrl
        {
            get
            {
                string siteUrl = string.Empty;
                bool useWildcardInclusion = this.DdlHostHeaderPrefixes.SelectedItem.Value.Substring(0, 1) == "0";

                if (useWildcardInclusion)
                {
                    siteUrl = string.Concat(SpanUrlProtocol.InnerText, this.TxtSiteUrl.Text, this.DdlHostHeaderPrefixes.SelectedItem.Text, this.TxtSiteUrlSuffix.Text);
                }
                else
                {
                    siteUrl = string.Concat(SpanUrlProtocol.InnerText, this.TxtSiteUrl.Text, this.DdlHostHeaderPrefixes.SelectedItem.Text);
                }
                return siteUrl;
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
        }

        protected void BtnCreateSite_Click(object sender, EventArgs e)
        {
            if (this.Page.IsValid)
            {
                SPWebApplication spWebapplication = this.Selector.CurrentItem;
                string siteUrl = this.SiteUrl;
                string siteTitle = TxtCreateSiteTitle.Text;
                string siteDescription = TxtCreateSiteDescription.Text;
                uint language = uint.Parse(this.InputFormTemplatePickerControl.SelectedWebLanguage);
                int compatibilityLevel = int.Parse(this.InputFormTemplatePickerControl.SelectedSiteCompatibilityLevel, CultureInfo.InvariantCulture);
                string webTemplate = this.InputFormTemplatePickerControl.SelectedWebTemplate;

                string quotaTemplate = GetSelectedQuotaTemplate();

                SPContentDatabase spContentDatabase = this.GetSelectedContentDatabase(spWebapplication);
                SPSiteSubscription spiteSubscription = null;

                Contact primaryContact = new Contact(this.PickerOwner);
                Contact secondaryContact = new Contact(this.PickerOwner2);

                CreateHostNamedSite(spWebapplication, spContentDatabase, spiteSubscription, siteUrl, siteTitle, siteDescription, language, compatibilityLevel, webTemplate, primaryContact, secondaryContact, quotaTemplate);
            }
        }

        protected void BtnCancel_Click(object sender, EventArgs e)
        {
            SPScenarioContext context = null;
            try
            {
                context = SPScenarioContext.GetContext(this, CultureInfo.CurrentCulture);
            }
            catch { }

            if (context != null)
            {
                context.TransitionToCancelPage(true);
            }
            else
            {
                SPUtility.Redirect("/applications.aspx", SPRedirectFlags.Default, this.Context);
            }
        }

        public void OnContextChange(object sender, EventArgs e)
        {
            string strQTMaxStorage;
            SPWebApplication spWebApplication = null;
            Button btnCreateSite = this.BtnCreateSite;
            Button btnCreateSiteTop = this.BtnCreateSiteTop;
            bool currentItem = this.Selector.CurrentItem != null;
            bool flag = currentItem;
            btnCreateSiteTop.Enabled = currentItem;
            btnCreateSite.Enabled = flag;
            this.LabelErrorMessage.Text = string.Empty;

            if (this.Selector.CurrentItem != null)
            {
                spWebApplication = this.Selector.CurrentItem;

                this.InputFormTemplatePickerControl.CompatibilityRange = spWebApplication.CompatibilityRange;

                HttpServerUtility server = base.Server;
                string currentName = this.Selector.CurrentName;
                char[] chrArray = new char[] { '/' };

                string name = SPResource.GetString("NoQuota", new object[0]);
                this.DdlQuotaTemplate.Items.Clear();
                int quotaSelectedIndex = 0;
                int nbQuota = 1;
                string strNotApplicable = SPResource.GetString("NotApplicable", new object[0]);
                string strMegaBytes = SPResource.GetString("MegaBytes", new object[0]);
                string defaultQuotaTemplate = this.Selector.CurrentItem.DefaultQuotaTemplate;
                this.DdlQuotaTemplate.Items.Add(new ListItem(SPHttpUtility.NoEncode(SPResource.GetString("NoQuota", new object[0])), SPHttpUtility.NoEncode(name)));

                string htmlOutput = string.Concat("<input type=\"hidden\" id=\"HidQTMaxStorage", SPHttpUtility.HtmlEncode(name), "\" value=\"\">");
                htmlOutput = string.Concat(htmlOutput, "<input type=\"hidden\" id=\"HidQTMaxUsers", SPHttpUtility.HtmlEncode(name), "\" value=\"\">");

                this.PickerOwner.WebApplicationId = this.Selector.CurrentItem.Id;
                this.PickerOwner2.WebApplicationId = this.Selector.CurrentItem.Id;

                foreach (SPQuotaTemplate quotaTemplate in base.GlobalAdmin.Config.QuotaTemplates)
                {
                    this.DdlQuotaTemplate.Items.Add(new ListItem(SPHttpUtility.NoEncode(quotaTemplate.Name), SPHttpUtility.NoEncode(quotaTemplate.Name)));
                    if (defaultQuotaTemplate == quotaTemplate.Name)
                    {
                        quotaSelectedIndex = nbQuota;
                    }
                    nbQuota++;

                    if (quotaTemplate.StorageMaximumLevel == (long)0)
                    {
                        strQTMaxStorage = strNotApplicable;
                    }
                    else
                    {
                        long storageMaximumLevel = quotaTemplate.StorageMaximumLevel / (long)1048576;
                        strQTMaxStorage = string.Concat(storageMaximumLevel.ToString(), strMegaBytes);
                    }

                    string strQTMaxUsers = (quotaTemplate.InvitedUserMaximumLevel == 0 ? strNotApplicable : quotaTemplate.InvitedUserMaximumLevel.ToString());
                    htmlOutput = string.Concat(htmlOutput, "<input type=\"hidden\" id=\"HidQTMaxStorage", SPHttpUtility.HtmlEncode(quotaTemplate.Name), "\" value=\"", SPHttpUtility.HtmlEncode(strQTMaxStorage));
                    htmlOutput = string.Concat(htmlOutput, "\"><input type=\"hidden\" id=\"HidQTMaxUsers", SPHttpUtility.HtmlEncode(quotaTemplate.Name), "\" value=\"", SPHttpUtility.HtmlEncode(strQTMaxUsers));
                    htmlOutput = string.Concat(htmlOutput, "\">");

                }
                this.LiteralHiddenQuotaTemplates.Text = SPHttpUtility.NoEncode(htmlOutput);
                this.DdlQuotaTemplate.SelectedIndex = quotaSelectedIndex;

                foreach (SPContentDatabase contentDatabase in spWebApplication.ContentDatabases)
                {
                    this.DdlContentDatabase.Items.Add(new ListItem(SPHttpUtility.NoEncode(contentDatabase.Name), SPHttpUtility.NoEncode(contentDatabase.Id)));
                }

                SortedDictionary<string, string> hostHeaderPrefixes = new SortedDictionary<string, string>();
                foreach (SPPrefix sPPrefix in SPWebService.ContentService.HostHeaderPrefixes)
                {
                    string prefixUrl = "/" + sPPrefix.Name + "/";

                    if (string.IsNullOrEmpty(sPPrefix.Name))
                    {
                        prefixUrl = "/";
                    }

                    if (sPPrefix.PrefixType == SPPrefixType.WildcardInclusion)
                    {
                        hostHeaderPrefixes.Add(prefixUrl, "0:" + prefixUrl);
                    }
                    else if (sPPrefix.PrefixType == SPPrefixType.ExplicitInclusion)
                    {
                        hostHeaderPrefixes.Add(prefixUrl, "1:" + prefixUrl);
                    }
                }

                this.DdlHostHeaderPrefixes.DataSource = hostHeaderPrefixes;
                this.DdlHostHeaderPrefixes.DataTextField = "key";
                this.DdlHostHeaderPrefixes.DataValueField = "value";
                this.DdlHostHeaderPrefixes.DataBind();

                Uri webAppUri = spWebApplication.GetResponseUri(SPUrlZone.Default);
                SpanUrlProtocol.InnerText = webAppUri.Scheme + Uri.SchemeDelimiter;
            }
        }

        private void CreateHostNamedSite(SPWebApplication webApp, SPContentDatabase database, SPSiteSubscription siteSubscription, string siteUrl, string title, string description, uint nLCID, int compatibilityLevel, string webTemplate, Contact ownerContact, Contact secondaryContact, string quotaTemplate)
        {
            SPSiteCollection sites = webApp.Sites;
            siteUrl = siteUrl.Trim();
            Uri siteUri = new Uri(siteUrl, UriKind.Absolute);

            if (!Uri.UriSchemeHttps.Equals(siteUri.Scheme, StringComparison.OrdinalIgnoreCase) && !Uri.UriSchemeHttp.Equals(siteUri.Scheme, StringComparison.OrdinalIgnoreCase))
            {
                throw new ArgumentException(SPUtility.GetLocalizedString("$Resources:SharePointHNSC.spadmin, createhostnamedsite_InvalidURLError", "SharePointHNSC.spadmin", 1033), "Url");
            }

            //Reflection of: SPSite.Add(SPContentDatabase database, SPSiteSubscription siteSubscription, string siteUrl, string title, string description, uint nLCID, int compatibilityLevel, string webTemplate, string ownerLogin, string ownerName, string ownerEmail, string secondaryContactLogin, string secondaryContactName, string secondaryContactEmail, string quotaTemplate, string sscRootWebUrl, bool useHostHeaderAsSiteName, bool overrideCompatibilityRestriction)
            Type type = sites.GetType();
            Type[] signature = new Type[] { typeof(SPContentDatabase), typeof(SPSiteSubscription), typeof(string), typeof(string), typeof(string), typeof(uint), typeof(int), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(bool), typeof(bool) };
            MethodInfo methodInfo = type.GetMethod("Add", BindingFlags.NonPublic | BindingFlags.Instance, null, signature, null);
            object[] parametersArray = new object[] { database, siteSubscription, siteUrl, title, description, nLCID, compatibilityLevel, webTemplate, ownerContact.Login, ownerContact.Name, ownerContact.Email, secondaryContact.Login, secondaryContact.Name, secondaryContact.Email, quotaTemplate, null, true, false };

            SPLongOperation spLongOperation = new SPLongOperation(this);
            spLongOperation.Begin();

            SPSite newSite = (SPSite)methodInfo.Invoke(sites, parametersArray);

            string redirectUrl = string.Format("/_admin/SharePointHNSC/HostNameSiteCreated.aspx?SiteId={0}", newSite.ID);
            redirectUrl = base.AppendSourceToUrl(redirectUrl);
            if (base.IsPopUI)
            {
                redirectUrl = string.Concat(redirectUrl, "&IsDlg=1");
            }

            spLongOperation.End(redirectUrl, SPRedirectFlags.Static, HttpContext.Current, null);
        }

        private string GetSelectedQuotaTemplate()
        {
            string quoteTemplate = null;

            if (this.DdlQuotaTemplate.SelectedIndex != 0)
            {
                quoteTemplate = this.DdlQuotaTemplate.SelectedValue;
            }

            return quoteTemplate;
        }

        private SPContentDatabase GetSelectedContentDatabase(SPWebApplication spWebapplication)
        {
            Guid contentDatabaseId = new Guid(this.DdlContentDatabase.SelectedValue);
            return (from SPContentDatabase contentDatabase in spWebapplication.ContentDatabases
                    where contentDatabase.Id.Equals(contentDatabaseId)
                    select contentDatabase).FirstOrDefault();
        }

        internal class Contact
        {
            private string _name = null;
            private string _email = null;
            private string _login = null;

            public string Name
            {
                get
                {
                    return this._name;
                }
            }

            public string Email
            {
                get
                {
                    return this._email;
                }
            }

            public string Login
            {
                get
                {
                    return this._login;
                }
            }

            public Contact(PeopleEditor peopleEditor)
            {
                if (peopleEditor.ResolvedEntities.Count != 0)
                {
                    PickerEntity pickerEntity = (PickerEntity)peopleEditor.ResolvedEntities[0];
                    this._login = pickerEntity.Key;
                    this._name = pickerEntity.DisplayText;
                    this._email = (string)pickerEntity.EntityData["Email"];
                }
            }
        }

        protected void ValSiteUrl_ServerValidate(object source, ServerValidateEventArgs args)
        {
            Uri uriToValidate;
            if (Uri.TryCreate(this.SiteUrl, UriKind.Absolute, out uriToValidate))
            {
                args.IsValid = !Path.HasExtension(uriToValidate.AbsoluteUri) && (uriToValidate.Scheme.Equals(Uri.UriSchemeHttp) || uriToValidate.Scheme.Equals(Uri.UriSchemeHttps));
            }
            else
            {
                args.IsValid = false;
            }
        }
    }
}